ext.define('extension.gui', function() {

var messages = extension.messages;
var utils = extension.utils;

var Sidebar = {
    show: function() {
        if (!this.isOpen())
            this.parent.appendChild(this.host);
    },
    hide: function() {
        if (this.isOpen())
            this.parent.removeChild(this.host);
    },
    isOpen: function() {
        return this.parent.contains(this.host);
    },
    addNote: function(tag) {
        var height = utils.getDocumentHeight();
        var top = Math.ceil(utils.clamp(tag.offset, 0, height) / height * 100);
        var element = this.createNote();
        element.querySelector('.content').classList.add(tag.color);
        element.querySelector('.body').innerText = tag.text;
        element.style.top = top + '%';
        element.dataset.offset = tag.offset;
        this.getElement().appendChild(element);
    },
    removeNote: function(element) {
        this.getElement().removeChild(element);
    },
    clearNotes: function() {
        this.getElement().textContent = '';
    },
    searchNote: function(offset) {
        var elms = this.shadow.querySelectorAll('.note');
        for (var i = 0; i < elms.length; i++) {
            if (elms[i].dataset.offset == offset)
                return elms[i];
        }
    },
    createNote: function() {
        return this.templateNote.cloneNode(true).querySelector('.note');
    },
    hasNotes: function() {
        return this.getElement().childElementCount > 0;
    },
    getNotes: function() {
        return Array.prototype.slice.call(this.getElement().children, 0);
    },
    getElement: function() {
        return this.shadow.querySelector('.sidebar');
    },
    lock: function(enable) {
        this.getElement().classList.toggle('locked', enable);
    },
    isLocked: function() {
        return this.getElement().classList.contains('locked');
    },
    collapseNotes: function() {
        var elms = this.shadow.querySelectorAll('.note.expand');
        for (var i = 0; i < elms.length; i++)
            elms[i].classList.remove('expand');
    },
    getInstance: function() {
        if (Sidebar._instance == null)
            Sidebar._instance = createSidebarWidget();
        return Sidebar._instance;
    },
    handleEvent: function(event) {
        if (this.isLocked())
            return;

        var target = event.target;
        var notes = this.shadow.querySelectorAll('.note');
        var note = utils.findParentElement(notes, target);
        if (!note)
            return;

        var type = event.type;

        if (type === 'mouseover' || type === 'mouseout') {
            if (note !== utils.findParentElement(notes, event.relatedTarget)) {
                if (!note.querySelector('.lock').classList.contains('locked'))
                    note.classList.toggle('expand', type === 'mouseover');
            }
        }

        if (type === 'click') {
            var offset = note.dataset.offset;
            if (target.classList.contains('delete')) {
                if (!note.querySelector('.lock').classList.contains('locked'))
                    messages.send('view-sidebar-remove', offset);
            }
            else if (target.classList.contains('edit'))
                messages.send('view-sidebar-edit', offset);
            else if (target.classList.contains('lock'))
                target.classList.toggle('locked');
            else
                messages.send('view-sidebar-click', offset);
        }
    }
};

function createTemplateNote() {
    var note = document.createElement('div');
    note.className = 'note';
    var content = document.createElement('div');
    content.className = 'content';
    var erase = document.createElement('div');
    erase.className = 'control delete';
    var edit = document.createElement('div');
    edit.className = 'control edit';
    var lock = document.createElement('div');
    lock.className = 'control lock';
    var body = document.createElement('div');
    var controls = document.createElement('div');
    controls.className = 'controls';
    body.className = 'body';
    var plus = document.createElement('div');
    plus.className = 'plus';
    controls.appendChild(erase);
    controls.appendChild(edit);
    controls.appendChild(lock);
    content.appendChild(controls);
    content.appendChild(body);
    content.appendChild(plus);
    note.appendChild(content);
    var tmpl = document.createElement('template');
    tmpl.appendChild(note);
    return tmpl;
}

function createSidebarElement() {
    var host = document.createElement('div');
    host.style.cssText = 'position:fixed;right:1px;top:40px;bottom:50px;width:0;z-index:2147483646';
    var style = document.createElement('style');
    style.innerText = utils.createShadowStyle('sidebar.css');
    var container = document.createElement('div');
    container.className = 'sidebar';
    var shadow = utils.getShadowRoot(host);
    shadow.appendChild(style);
    shadow.appendChild(container);
    return host;
}

function createSidebarWidget() {
    var host = createSidebarElement();
    var widget = utils.createWidget(Sidebar, host, document.body);
    widget.templateNote = createTemplateNote();
    var shadow = widget.shadow;
    shadow.querySelector('.sidebar').addEventListener('mouseover', widget);
    shadow.querySelector('.sidebar').addEventListener('mouseout', widget);
    shadow.querySelector('.sidebar').addEventListener('click', widget);
    return widget;
}

return {
    Sidebar: Sidebar
};

});
